﻿using AspectCore.Configuration;
using AspectCore.Extensions.DependencyInjection;
using AspectCore.Injector;
using CacheAOP_AspectCore.AOPCache;
using CacheAOP_AspectCore.Service;
using CacheManager;
using CacheManager.IOC;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Reflection;

namespace CacheAOP_AspectCore
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            services.AddScoped<ICacheManager, DistributedCacheManager>();
            services.AddScoped<IDateTimeService, DateTimeService>();

            var assembly = this.GetType().GetTypeInfo().Assembly;
            this.AddBLLClassToServices(assembly, services);//注入bll 

            var redisConnectionString = Configuration.GetSection("ConnectionStrings")["Redis"];
            services.AddDistributedRedisCache(option =>
            {
                option.Configuration = redisConnectionString;//redis连接字符串
                option.InstanceName = "redis";//Redis实例名称
            });
            //注入aspectcore容器
            //注入aspectcore的缓存连接器
            var container = services.ToServiceContainer();
            container.AddType<CachingInterceptor>();
            container.Configure(config =>
            {
                config.Interceptors.AddTyped<CachingInterceptor>(method => typeof(ICaching).IsAssignableFrom(method.DeclaringType));
            });
            services.UseCsRedisClient(redisConnectionString);
            services.AddOptions();
            //AspectCoreContainer.BuildServiceProvider(services);
            return container.Build();
        }

        public void AddBLLClassToServices(Assembly assembly, IServiceCollection services)
        {
            var types = assembly.GetTypes().ToList();
            foreach (var item in types.Where(x => x.Name.EndsWith("BLL", StringComparison.OrdinalIgnoreCase) && x.IsClass))
            {
                services.AddSingleton(item);
            }
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
        }
    }
}
